# -*- coding: utf-8 -*-
"""
 Created by wq.wang on 2017/12/22
"""
import logging
import os
from importlib import import_module

from wserver.base.exception import SrvNotExist, ApiNotExist
from wserver.base.service import SERVICE

_logger = logging.getLogger(__name__)


class WServer():
    _instance = None

    def __new__(cls, *args, **kwargs):
        """
        单实例
        :param args:
        :param kwargs:
        :return:
        """
        if cls._instance:
            return cls._instance
        else:
            return super().__new__(cls)

    def __init__(self, mods, must_load=True) -> None:
        if isinstance(mods, str):
            mods = [mods]
        self.mods = mods
        self._load_module(must_load)
        self._swagger = None

    def get_swagger_doc(self, hostname="", pre_uri="/", description="",
                        version="1.0.0", title="", termsOfService=""):
        if not self._swagger:
            paths = {}
            for service in SERVICE.values():
                for tapi in service._wapis.values():
                    paths.setdefault(tapi._wapi_path, {}).update({tapi._wapi_method: tapi.swagger})
            self._swagger = {
                "swagger": "2.0",
                "info": {
                    "description": description,
                    "version": version,
                    "title": title,
                    "termsOfService": termsOfService,
                    "contact": {
                        "email": "wq.wang@shunwang.com"
                    }
                },
                "host": hostname,
                "basePath": pre_uri,
                "tags": [{"name": service.__name__, "description": (service.__doc__ or "").strip()} for service in
                         SERVICE.values()],
                "paths": paths
            }
        return self._swagger

    def handler(self, service, api, *args, **kwargs):

        if service not in SERVICE:
            raise SrvNotExist()
        service = SERVICE[service]
        if api not in service._wapis:
            raise ApiNotExist()

        api = service._wapis[api]
        return service.handle(api, *args, **kwargs)

    def _load_module(self, must_load=True):

        for mod in self.mods:
            try:
                import_module(mod)
            except Exception as e:
                if must_load:
                    raise e
                _logger.exception("加载%s失败" % mod)

    @property
    def _default_static_doc(self):
        return os.path.join(os.path.dirname(__file__), "static")
